package com.wstuo.itsm.itsop.itsopuser.service;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.config.dictionary.dao.IDataDictionaryItemsDAO;
import com.wstuo.common.config.dictionary.entity.DataDictionaryItems;
import com.wstuo.itsm.itsop.itsopuser.dao.IITSOPUserDAO;
import com.wstuo.itsm.itsop.itsopuser.dto.ITSOPUserDTO;
import com.wstuo.itsm.itsop.itsopuser.dto.ITSOPUserGridDTO;
import com.wstuo.itsm.itsop.itsopuser.dto.ITSOPUserQueryDTO;
import com.wstuo.itsm.itsop.itsopuser.entity.ITSOPUser;
import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.exception.ApplicationException;
import com.wstuo.common.file.csv.CSVReader;
import com.wstuo.common.file.csv.CSVWriter;
import com.wstuo.common.security.dao.ICompanyDAO;
import com.wstuo.common.security.dao.IOrganizationDAO;
import com.wstuo.common.security.dao.IRoleDAO;
import com.wstuo.common.security.dao.IUserDAO;
import com.wstuo.common.security.dto.CompanyDTO;
import com.wstuo.common.security.entity.Company;
import com.wstuo.common.security.entity.Organization;
import com.wstuo.common.security.entity.Role;
import com.wstuo.common.security.entity.User;
import com.wstuo.common.security.service.IRoleService;
import com.wstuo.common.security.service.IUserInfoService;
import com.wstuo.common.security.utils.FileEncodeUtils;
import com.wstuo.common.security.utils.LanguageContent;
import com.wstuo.common.util.StringUtils;

/**
 * 外包客户的业务处理类
 * @author QXY
 *
 */
public class ITSOPUserService implements IITSOPUserService {
	private static final Logger LOGGER = Logger.getLogger(ITSOPUserService.class);
	@Autowired
	private IITSOPUserDAO itsopUserDAO;
	@Autowired
	private IUserDAO userDAO;
	@Autowired
	private IRoleDAO roleDAO;
	@Autowired
	private IOrganizationDAO organizationDAO;
	@Autowired
	private IDataDictionaryItemsDAO dataDictionaryItemsDAO;
	@Autowired
	private IUserInfoService userInfoService;
	@Autowired
	private ICompanyDAO companyDAO;

	/**
	 * 分页查找外包客户.
	 * 
	 * @param qdto
	 * @return PageDTO
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public PageDTO findITSOPUserPager(ITSOPUserQueryDTO qdto) {

		PageDTO p = itsopUserDAO.findITSOPUserPager(qdto);
		List<ITSOPUser> entities = p.getData();
		List<ITSOPUserGridDTO> dtos = new ArrayList<ITSOPUserGridDTO>(
				entities.size());

		for (ITSOPUser entity : entities) {
			ITSOPUserGridDTO dto = new ITSOPUserGridDTO();
			ITSOPUserGridDTO.entity2dto(entity, dto);
			entity2dto(entity, dto);
			dtos.add(dto);
		}

		p.setData(dtos);
		return p;
	}

	/**
	 * 实体转DTO
	 * 
	 * @param entity
	 * @param dto
	 */
	private void entity2dto(ITSOPUser entity, ITSOPUserGridDTO dto) {

		List<User> technicians = entity.getTechnicians();

		if (technicians != null && technicians.size() > 0) {

			String[] userNames = new String[technicians.size()];
			String[] technicianNameFullName = new String[technicians.size()];
			int z = 0;
			for (User u : technicians) {
				userNames[z] = u.getLoginName();
				technicianNameFullName[z] = u.getFullName();
				z++;
			}
			dto.setTechnicianNames(userNames);
			dto.setTechnicianNameFullName(technicianNameFullName);
		}

		DataDictionaryItems type = entity.getType();

		if (type != null) {
			dto.setTypeNo(type.getDcode());
			dto.setTypeName(type.getDname());
		}

	}

	/**
	 * DTO转换实体
	 * 
	 * @param dto
	 * @param entity
	 */
	private void dto2entity(ITSOPUserDTO dto, ITSOPUser entity) {

		List<String> technicianNames = dto.getTechnicianNames();

		if (technicianNames != null && technicianNames.size() > 0) {// 负责的技术员
			String[] userNames = technicianNames
					.toArray(new String[technicianNames.size()]);
			entity.setTechnicians(userDAO.findByUserNames(userNames));
		}

		if (dto.getTypeNo() != null && dto.getTypeNo() != 0) {// 客户类型
			entity.setType(dataDictionaryItemsDAO.findById(dto.getTypeNo()));
		} else {
			entity.setType(null);
		}
	}

	/**
	 * 添加外包客户.
	 * 
	 * @param dto
	 *            ITSOPUserDTO 外包客户DTO
	 */
	@Transactional
	public String addITSOPUser(ITSOPUserDTO dto) {
		String password = "";
		if (dto != null && StringUtils.hasText(dto.getOrgName())) {
			ITSOPUser itsopUser = new ITSOPUser();
			ITSOPUserDTO.dto2entity(dto, itsopUser);
			dto2entity(dto, itsopUser);
			itsopUser.setOrgType("itsop");
			if(dto.getCompanyNo()!= null){
				Company cp=companyDAO.findById(dto.getCompanyNo());
				if(cp!=null && cp.getLogo()!=null){
					itsopUser.setLogo(cp.getLogo());
				}
			}
			itsopUserDAO.save(itsopUser);
			if(itsopUser.getParentOrg()!=null){
				itsopUser.setPath(itsopUser.getParentOrg().getPath()+itsopUser.getOrgNo()+"/");
			}else{
				itsopUser.setPath(itsopUser.getOrgNo()+"/");
			}
			User user = createITSOPUser(itsopUser.getOrgNo());// 创建默认用户，设置角色权限
			password = user.getLoginName();//默认登录名和密码一致
			// 赋值字符串
			itsopUser.setTechnicianNames(itsopUser.generateTcNames());
			dto.setOrgNo(itsopUser.getOrgNo());
		} else {
			throw new ApplicationException("ERROR_DATA_WRONG\n");
		}
		return password;
	}

	/**
	 * 创建一个外包商管理员用户.
	 * 
	 * @param itsopNo
	 *            外包客户编号.
	 */
	private User createITSOPUser(Long itsopNo) {
		Random random = new Random();
		String loginName="cu"+Math.abs(random.nextInt(1000))+ itsopNo;
		User user = userDAO.findUniqueBy("loginName", loginName);
		if (user == null) {
			user = new User();
			// 用户基本信息
			user.setCompanyNo(itsopNo);
			Organization org = organizationDAO.findById(itsopNo);
			if (org != null) {
				user.setOrgnization(org);
			}
			user.setFirstName("ITSOP_");
			user.setLastName("" + itsopNo);
			user.setLoginName(loginName);
			user.setPassword(loginName);
			user.setUserState(true);
			user.setFullName("");
			// 设置角色
			Set<Role> userRole = new HashSet<Role>();
			userRole.add(roleDAO.findUniqueBy("roleCode", IRoleService.ROLE_ITSOP_MANAGEMENT));
			user.setRoles(userRole);
			userDAO.save(user);
		}
		return user;
	}

	/**
	 * 修改外包客户.
	 * 
	 * @param dto
	 */
	@Transactional
	public void updateITSOPUser(ITSOPUserDTO dto) {

		if (dto != null && dto.getOrgNo() != null) {
			ITSOPUser itsopUser = itsopUserDAO.findById(dto.getOrgNo());
			if (itsopUser != null) {
				if(itsopUser.getLogo()!=null){
					dto.setLogo(itsopUser.getLogo());
				}
				ITSOPUserDTO.dto2entity(dto, itsopUser);
				dto2entity(dto, itsopUser);
				// 赋值字符串
				itsopUser.setTechnicianNames(itsopUser.generateTcNames());

				itsopUserDAO.merge(itsopUser);
				if(itsopUser.getParentOrg()!=null){
					itsopUser.setPath(itsopUser.getParentOrg().getPath()+itsopUser.getOrgNo()+"/");
				}else{
					itsopUser.setPath(itsopUser.getOrgNo()+"/");
				}
			}
		}
	}

	/**
	 * 删除外包客户（多个）.
	 * 
	 * @param ids
	 */
	@Transactional
	public void deleteITSOPUser(Long[] ids) {

		if (ids != null && ids.length > 0) {
			itsopUserDAO.deleteByIds(ids);
			deleteSubUsers(ids);
		}
	}

	/**
	 * 删除外包客户（单个）.
	 * 
	 * @param id
	 */
	@Transactional
	public void deleteITSOPUser(Long id) {
		if (id!=null&&id!=0){
			Long[] ids=new Long[] {id};
			deleteITSOPUser(ids);
			deleteSubUsers(ids);
		}
	}

	/**
	 * 根据服外包客户删除所属用户.
	 * 
	 * @param itsopIds
	 *            外包商编号
	 */
	private void deleteSubUsers(Long[] itsopIds) {

		for (Long l : itsopIds) {

			List<User> users = userDAO.findBy("companyNo", l);
			if (users != null && users.size() > 0) {
				userDAO.deleteAll(users);
			}
		}
	}
	/**
	 * 我所在的公司和我负责的客户
	 * @return Long[]
	 */
	@Transactional
	public Long[] findMyAllCustomer(String loginName) {
		Set<Long> companyNos = new HashSet<Long>();// 唯一集合
		//查出我负责的外包客户
		List<ITSOPUser> itsopUsers = itsopUserDAO.findMyRelatedCustomer(loginName);
		for(ITSOPUser itsopUser : itsopUsers){
			companyNos.add(itsopUser.getOrgNo());
		}
		//我所在的公司
		User user = userDAO.findUniqueBy("loginName", loginName);
		if(user!=null){
			companyNos.add(user.getCompanyNo());
		}
		Long[] toArray = companyNos.toArray(new Long[companyNos.size()]);
		return toArray;
	}
	
	/**
	 * 分页查找我在的公司和我负责外包客户.
	 * 
	 * @param qdto
	 * @return PageDTO
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public PageDTO findMySupportITSOPUserPager(ITSOPUserQueryDTO qdto) {
		PageDTO p = itsopUserDAO.findITSOPUserPager(qdto);
		List<ITSOPUser> entities = (List<ITSOPUser>) p.getData();
		List<ITSOPUserGridDTO> dtos = new ArrayList<ITSOPUserGridDTO>();

		for (ITSOPUser entity : entities) {
			ITSOPUserGridDTO dto = new ITSOPUserGridDTO();
			ITSOPUserGridDTO.entity2dto(entity, dto);
			entity2dto(entity, dto);
			dtos.add(dto);
		}
		p.setData(dtos);
		return p;
	}

	/**
	 * 导出数据方法
	 * 
	 * @throws Exception
	 */
	@Transactional
	public InputStream exportITSOPUser(ITSOPUserQueryDTO qdto) {
		StringWriter sw = new StringWriter();
		CSVWriter csvw = new CSVWriter(sw);
		List<String[]> data = new ArrayList<String[]>();
		LanguageContent lc = LanguageContent.getInstance();
		ByteArrayInputStream stream = null;
		data.add(new String[] {
				lc.getContent("common.id"),
				lc.getContent("report.client.name"),
				lc.getContent("label.telephone"),
				lc.getContent("label.e-mail"),
				lc.getContent("label.user.fax"),
				lc.getContent("label.address"),
				lc.getContent("label.itsop.corporate"),
				lc.getContent("label.itsop.companySize"),
				lc.getContent("label.itsop.regNumber"),
				lc.getContent("label.itsop.regCapital") + "("
						+ lc.getContent("label.itsop.wan") + ")",
				lc.getContent("label.itsop.technicianInCharge"),
				lc.getContent("report.classify") });
		PageDTO p = itsopUserDAO.findITSOPUserPager(qdto);
		List<ITSOPUser> entities = (List<ITSOPUser>) p.getData();
		if (entities != null && entities.size() > 0) {
			String setup = "", techNames = "", companySize = "";
			int ii = 0;
			for (ITSOPUser item : entities) {
				setup = "";
				techNames = "";
				companySize = "";
				if (item != null && item.getType() != null) {
					setup = item.getType().getDname();
					techNames = item.generateTcNames();
				}
				if (techNames != null && techNames.length() > 0)
					techNames = techNames.substring(0, techNames.length() - 1);
				if (item != null) {
					try {
						ii = Integer.parseInt(item.getCompanySize());
					} catch (Exception e) {
						LOGGER.error(e);
						ii = 0;
					}
				}

				switch (ii) {
				case 1:
					companySize = lc.getContent("label.itsop.moreThan50");
					break;
				case 2:
					companySize = lc.getContent("label.itsop.moreThan100");
					break;
				case 3:
					companySize = lc.getContent("label.itsop.moreThan200");
					break;
				case 4:
					companySize = lc.getContent("label.itsop.moreThan500");
					break;
				default:
					companySize = lc.getContent("label.itsop.moreThan1000");
					break;
				}
				if(item!=null){
					data.add(new String[] { item.getOrgNo() + "",
							item.getOrgName(), item.getOfficePhone(),
							item.getEmail(), item.getOfficeFax(),
							item.getAddress(), item.getCorporate(), companySize,
							item.getRegNumber(), item.getRegCapital() + "",
							techNames, setup, });
				}
			}
		}
		csvw.writeAll(data);
		byte[] bs = null;
		try {
			bs = sw.getBuffer().toString().getBytes("GBK");
		} catch (UnsupportedEncodingException e1) {
			LOGGER.error(e1);
		}
		 stream = new ByteArrayInputStream(bs);
		 
		return stream;
	}

	/**
	 * 导入数据方法.
	 * 
	 * @param importCSVFile
	 * @return String
	 */
	@Transactional
	public String importITSOPUser(File importCSVFile, int fix) {
		int insert = 0;
		int update = 0;
		int total = 0;
		int failure = 0;
		try {
			String fileEncode = FileEncodeUtils.getFileEncode(importCSVFile);
			Reader rd = new InputStreamReader(
					new FileInputStream(importCSVFile), fileEncode);// 以字节流方式读取数据
			CSVReader reader = new CSVReader(rd);
			String[] line = null;
			try {
				if (fix == 0) {
					while ((line = reader.readNext()) != null) {
						ITSOPUser itsopUser = itsopUserDAO.findUniqueBy(
								"orgName", line[1].toString());
						if (itsopUser != null) {
							return "comeBack";
						}
					}
				}
				fix = 1;
				if (fix == 1) {
					Reader rds = new InputStreamReader(new FileInputStream(
							importCSVFile), fileEncode);// 以字节流方式读取数据
					reader = new CSVReader(rds);
					String[] lines = null;
					String csize = "";
					while ((lines = reader.readNext()) != null) {
						ITSOPUserDTO dto = new ITSOPUserDTO();
						ITSOPUser itsopUser = itsopUserDAO.findUniqueBy(
								"orgName", lines[0].toString());
						dto.setOrgName(lines[0].toString());
						dto.setOfficePhone(lines[1].toString());
						dto.setEmail(lines[2].toString());
						dto.setOfficeFax(lines[3].toString());
						dto.setAddress(lines[4].toString());
						dto.setCorporate(lines[5].toString());
						csize = lines[6].toString();
						if (csize.contains("50"))
							dto.setCompanySize(1 + "");
						else if (csize.contains("100"))
							dto.setCompanySize(2 + "");
						else if (csize.contains("200"))
							dto.setCompanySize(3 + "");
						else if (csize.contains("500"))
							dto.setCompanySize(4 + "");
						else if (csize.contains("1000"))
							dto.setCompanySize(5 + "");
						else
							dto.setCompanySize(1 + "");
						dto.setRegNumber(lines[7].toString());
						dto.setRegCapital(Long.parseLong(lines[8]));
						if (lines[10] != null) {
							List<DataDictionaryItems> lis = dataDictionaryItemsDAO
									.findItemByGroupCodeAndName("itsopType",
											lines[10].toString());
							if (lis != null) {
								dto.setTypeNo(lis.get(0).getDcode());
							}
						}
						// 判断技术员是否存在
						dto.setTechnicianNamesStr(lines[9].toString());
						List<String> list = dto.getTechnicianNames();
						for (int i = 0; i < list.size(); i++) {
							User user = userDAO.findUniqueBy("loginName",
									list.get(i));
							if (user == null)
								return "userNUll";// 技术员不存在
						}

						if (itsopUser == null) {
							insert++;
							addITSOPUser(dto);
						} else {// 覆盖
							dto.setOrgNo(itsopUser.getOrgNo());
							updateITSOPUser(dto);
							update++;
						}
						total++;
					}
				}
				StringBuffer result = new StringBuffer();
				result.append("Total").append(total).append(",&nbsp;")
				.append("Insert").append(insert).append(",&nbsp;")
				.append("Update").append(update).append(",&nbsp;")
				.append("Failure").append(failure);
				
				return result.toString();
			} catch (Exception e) {
				LOGGER.error(e);
				return "IOError";
			}
		} catch (Exception e1) {
			LOGGER.error(e1);
			return "FileNotFound";
		}

	}

	/**
	 * 自动补全验证用户
	 * @param orgName
	 * @return Long[]
	 */
	public Long[] autoVerification(String orgName) {
		List<ITSOPUser> list = itsopUserDAO.findBy("orgName", orgName);
		Long[] result = null;
		if (list != null) {
			result = new Long[list.size()];
			for (int j = 0; j < list.size(); j++) {
				ITSOPUser itUser = list.get(j);
				result[j] = itUser.getOrgNo();
			}
		}
		return result;
	}
	
	/**
	 * 根据登录账号获取相关的公司信息(负责的公司、所在的公司)
	 * @param loginName
	 * @return 公司编号Long[]
	 */
	@Transactional
	public Long[] getRelatedCompanyByLoginName(String loginName){
		Long[] companyNoArray = new Long[]{};
		Map<String,String> companyInfoMap = new HashMap<String, String>();
		
		Set<Long> companyNos = new HashSet<Long>();// 唯一集合
		//查出我负责的外包客户
		List<ITSOPUser> itsopUsers = itsopUserDAO.findMyRelatedCustomer(loginName);
		for(ITSOPUser itsopUser : itsopUsers){
			companyNos.add(itsopUser.getOrgNo());
		}
		//我所在的公司
		CompanyDTO companyDto = userInfoService.findUserCompany(loginName);
		if(companyDto!=null && companyDto.getOrgNo()!=null && companyDto.getOrgName()!=null){
			companyNos.add(companyDto.getOrgNo());
			companyInfoMap.put(companyDto.getOrgNo().toString(), companyDto.getOrgName());
		}
		companyNoArray = companyNos.toArray(new Long[companyNos.size()]);
		
		return companyNoArray;
	}
	
	/**
	 * 取外包总数
	 * @return
	 */
	@Transactional
	public int getitsopAlreadyUsed(){
		List<ITSOPUser>  li=itsopUserDAO.findAll();
		return li.size();
	}
}
